import sdk from '../core';
import { config, configKey } from '../config';
import { ComType } from '../core/tool/component';
import { ItemType, RankingType } from '../shared/face/enums';
import { MailService } from './MailService';
import { staticToInstance } from './base/LegacyServiceAdapter';
import { ModernRankingService } from './ModernRankingService';
import { RankingItem } from '../shared/face';




/**
 * 排行榜服务类
 * 职责：
 * 1. 排行榜数据管理
 * 2. 排行榜计算和更新
 * 3. 排行榜奖励发放
 * 4. 排行榜数据持久化
 */
export class RankingService {
    
    // 排行榜数据缓存
    private static rankingCache: Map<RankingType, RankingItem[]> = new Map();
    
    // 上次结算时间
    private static lastSettlementTime: number = 0;
    
    // 结算间隔（7天）
    private static readonly SETTLEMENT_INTERVAL = 7 * 24 * 60 * 60 * 1000;
    
    // 结算时间（凌晨3点）
    private static readonly SETTLEMENT_HOUR = 3;
    
    /**
     * 初始化排行榜服务
     */
    @staticToInstance(ModernRankingService)
    static async init() {
        try {
            console.log('初始化排行榜服务...');
            
            // 加载排行榜数据
            await this.loadRankingData();
            
            // 检查是否需要结算
            await this.checkSettlement();
            
            console.log('排行榜服务初始化完成');
        } catch (error) {
            console.error('排行榜服务初始化失败:', error);
        }
    }
    
    /**
     * 加载排行榜数据
     */
    @staticToInstance(ModernRankingService)
    private static async loadRankingData() {
        try {
            const rankingData = await sdk.db.find('ranking_data');
            
            // 按类型分组数据
            const groupedData = new Map<RankingType, RankingItem[]>();
            
            rankingData.forEach((item: any) => {
                const type = item.type as RankingType;
                if (!groupedData.has(type)) {
                    groupedData.set(type, []);
                }
                groupedData.get(type)!.push({
                    playerId: item.playerId,
                    playerName: item.playerName,
                    playerEmoji: item.playerEmoji,
                    score: item.score,
                    rank: item.rank,
                    lastUpdateTime: item.lastUpdateTime
                });
            });
            
            // 更新缓存
            this.rankingCache = groupedData;
            
        } catch (error) {
            console.error('加载排行榜数据失败:', error);
        }
    }
    
    /**
     * 更新玩家排行榜数据
     * @param player 玩家对象
     * @param type 排行榜类型
     * @param score 分数
     */
    @staticToInstance(ModernRankingService)
    static async updatePlayerRanking(player: any, type: RankingType, score: number) {
        try {
            const baseCom = player.getComponent(ComType.base) as any;
            const rpgCom = player.getComponent(ComType.rpg) as any;
            const bagCom = player.getComponent(ComType.背包) as any;
            const signCom = player.getComponent(ComType.签到) as any;
            
            if (!baseCom) {
                console.error('玩家基础组件不存在');
                return;
            }
            
            // 根据类型获取实际分数
            let actualScore = score;
            switch (type) {
                case RankingType.等级:
                    actualScore = rpgCom ? rpgCom.level : 1;
                    break;
                case RankingType.金币:
                    actualScore = bagCom ? this.getGoldCount(bagCom) : 0;
                    break;
                case RankingType.签到:
                    actualScore = signCom ? signCom.signCount : 0;
                    break;
                case RankingType.战力:
                    actualScore = rpgCom ? rpgCom._fighting : 0;
                    break;
            }
            
            const rankingItem: RankingItem = {
                playerId: player.id,
                playerName: baseCom.nickName,
                playerEmoji: baseCom.emoji,
                score: actualScore,
                rank: 0, // 稍后计算
                lastUpdateTime: Date.now()
            };
            
            // 更新数据库
            await this.saveRankingItem(type, rankingItem);
            
            // 更新缓存
            await this.updateRankingCache(type);
            
        } catch (error) {
            console.error('更新排行榜数据失败:', error);
        }
    }
    
    /**
     * 获取金币数量
     * @param bagCom 背包组件
     * @returns 金币数量
     */
    @staticToInstance(ModernRankingService)
    private static getGoldCount(bagCom: any): number {
        try {
            const goldItem = bagCom.bag.find((item: any) => 
                item.type === ItemType.资源 && item.id === '1' // 假设金币的资源ID为1
            );
            return goldItem ? goldItem.count : 0;
        } catch (error) {
            return 0;
        }
    }
    
    /**
     * 保存排行榜项目到数据库
     * @param type 排行榜类型
     * @param item 排行榜项目
     */
    @staticToInstance(ModernRankingService)
    private static async saveRankingItem(type: RankingType, item: RankingItem) {
        try {
            const existingItems = await sdk.db.find('ranking_data', {
                type: type,
                playerId: item.playerId
            });
            const existingItem = existingItems.length > 0 ? existingItems[0] : null;
            
            if (existingItem) {
                // 更新现有记录
                await sdk.db.update('ranking_data', 
                    { type: type, playerId: item.playerId },
                    {
                        playerName: item.playerName,
                        playerEmoji: item.playerEmoji,
                        score: item.score,
                        lastUpdateTime: item.lastUpdateTime
                    }
                );
            } else {
                // 创建新记录
                await sdk.db.insert('ranking_data', {
                    type: type,
                    playerId: item.playerId,
                    playerName: item.playerName,
                    playerEmoji: item.playerEmoji,
                    score: item.score,
                    rank: 0,
                    lastUpdateTime: item.lastUpdateTime
                });
            }
        } catch (error) {
            console.error('保存排行榜数据失败:', error);
        }
    }
    
    /**
     * 更新排行榜缓存
     * @param type 排行榜类型
     */
    @staticToInstance(ModernRankingService)
    private static async updateRankingCache(type: RankingType) {
        try {
            const rankingData = await sdk.db.find('ranking_data', { type: type });
            
            // 按分数排序
            const sortedData = rankingData
                .map((item: any) => ({
                    playerId: item.playerId,
                    playerName: item.playerName,
                    playerEmoji: item.playerEmoji,
                    score: item.score,
                    rank: 0,
                    lastUpdateTime: item.lastUpdateTime
                }))
                .sort((a, b) => b.score - a.score);
            
            // 设置排名
            sortedData.forEach((item, index) => {
                item.rank = index + 1;
            });
            
            // 更新缓存
            this.rankingCache.set(type, sortedData);
            
            // 更新数据库中的排名
            for (const item of sortedData) {
                await sdk.db.update('ranking_data',
                    { type: type, playerId: item.playerId },
                    { rank: item.rank }
                );
            }
            
        } catch (error) {
            console.error('更新排行榜缓存失败:', error);
        }
    }
    
    /**
     * 获取排行榜数据
     * @param type 排行榜类型
     * @param limit 限制数量
     * @returns 排行榜数据
     */
    @staticToInstance(ModernRankingService)
    static getRankingData(type: RankingType, limit: number = 100): RankingItem[] {
        const rankingData = this.rankingCache.get(type) || [];
        return rankingData.slice(0, limit);
    }
    
    /**
     * 获取玩家排名
     * @param playerId 玩家ID
     * @param type 排行榜类型
     * @returns 排名，未上榜返回-1
     */
    @staticToInstance(ModernRankingService)
    static getPlayerRank(playerId: string, type: RankingType): number {
        const rankingData = this.rankingCache.get(type) || [];
        const playerRank = rankingData.find(item => item.playerId === playerId);
        return playerRank ? playerRank.rank : -1;
    }
    
    /**
     * 检查是否需要结算
     */
    @staticToInstance(ModernRankingService)
    private static async checkSettlement() {
        const now = Date.now();
        const lastSettlement = this.lastSettlementTime;
        
        // 如果从未结算过，设置为当前时间
        if (lastSettlement === 0) {
            this.lastSettlementTime = now;
            return;
        }
        
        // 检查是否到了结算时间
        const timeSinceLastSettlement = now - lastSettlement;
        if (timeSinceLastSettlement >= this.SETTLEMENT_INTERVAL) {
            await this.performSettlement();
        }
    }
    
    /**
     * 执行排行榜结算
     */
    @staticToInstance(ModernRankingService)
    private static async performSettlement() {
        try {
            console.log('开始执行排行榜结算...');
            
            // 获取所有排行榜数据
            const levelRanking = this.getRankingData(RankingType.等级, 100);
            const goldRanking = this.getRankingData(RankingType.金币, 100);
            const signRanking = this.getRankingData(RankingType.签到, 100);
            const powerRanking = this.getRankingData(RankingType.战力, 100);
            
            // 按玩家ID分组，收集每个玩家的所有排行榜奖励
            const playerRewards = new Map<string, {
                playerId: string;
                playerName: string;
                rewards: Array<{
                    type: RankingType;
                    rank: number;
                    expReward: number;
                }>;
                totalExpReward: number;
            }>();
            
            // 处理等级排行榜
            for (let i = 0; i < levelRanking.length; i++) {
                const player = levelRanking[i];
                if (player && player.rank <= 100) {
                    const expReward = this.calculateExpReward(player.rank);
                    if (expReward > 0) {
                        if (!playerRewards.has(player.playerId)) {
                            playerRewards.set(player.playerId, {
                                playerId: player.playerId,
                                playerName: player.playerName,
                                rewards: [],
                                totalExpReward: 0
                            });
                        }
                        const playerData = playerRewards.get(player.playerId)!;
                        playerData.rewards.push({
                            type: RankingType.等级,
                            rank: player.rank,
                            expReward
                        });
                        playerData.totalExpReward += expReward;
                    }
                }
            }
            
            // 处理金币排行榜
            for (let i = 0; i < goldRanking.length; i++) {
                const player = goldRanking[i];
                if (player && player.rank <= 100) {
                    const expReward = this.calculateExpReward(player.rank);
                    if (expReward > 0) {
                        if (!playerRewards.has(player.playerId)) {
                            playerRewards.set(player.playerId, {
                                playerId: player.playerId,
                                playerName: player.playerName,
                                rewards: [],
                                totalExpReward: 0
                            });
                        }
                        const playerData = playerRewards.get(player.playerId)!;
                        playerData.rewards.push({
                            type: RankingType.金币,
                            rank: player.rank,
                            expReward
                        });
                        playerData.totalExpReward += expReward;
                    }
                }
            }
            
            // 处理签到排行榜
            for (let i = 0; i < signRanking.length; i++) {
                const player = signRanking[i];
                if (player && player.rank <= 100) {
                    const expReward = this.calculateExpReward(player.rank);
                    if (expReward > 0) {
                        if (!playerRewards.has(player.playerId)) {
                            playerRewards.set(player.playerId, {
                                playerId: player.playerId,
                                playerName: player.playerName,
                                rewards: [],
                                totalExpReward: 0
                            });
                        }
                        const playerData = playerRewards.get(player.playerId)!;
                        playerData.rewards.push({
                            type: RankingType.签到,
                            rank: player.rank,
                            expReward
                        });
                        playerData.totalExpReward += expReward;
                    }
                }
            }
            
            // 处理战力排行榜
            for (let i = 0; i < powerRanking.length; i++) {
                const player = powerRanking[i];
                if (player && player.rank <= 100) {
                    const expReward = this.calculateExpReward(player.rank);
                    if (expReward > 0) {
                        if (!playerRewards.has(player.playerId)) {
                            playerRewards.set(player.playerId, {
                                playerId: player.playerId,
                                playerName: player.playerName,
                                rewards: [],
                                totalExpReward: 0
                            });
                        }
                        const playerData = playerRewards.get(player.playerId)!;
                        playerData.rewards.push({
                            type: RankingType.战力,
                            rank: player.rank,
                            expReward
                        });
                        playerData.totalExpReward += expReward;
                    }
                }
            }
            
            // 发送合并的奖励邮件
            for (const playerData of playerRewards.values()) {
                if (playerData.totalExpReward > 0) {
                    await this.sendCombinedRankingReward(playerData);
                }
            }
            
            // 更新结算时间
            this.lastSettlementTime = Date.now();
            
            // 保存结算时间到数据库
            await sdk.db.update('system_config', 
                { key: 'last_ranking_settlement' },
                { value: this.lastSettlementTime }
            );
            
            console.log('排行榜结算完成');
            
        } catch (error) {
            console.error('排行榜结算失败:', error);
        }
    }
    
    /**
     * 计算排行榜奖励经验
     * @param rank 排名
     * @returns 奖励经验值
     */
    @staticToInstance(ModernRankingService)
    private static calculateExpReward(rank: number): number {
        if (rank <= 10) {
            return 1000 - (rank - 1) * 50; // 第1名1000经验，第10名550经验
        } else if (rank <= 50) {
            return 500 - (rank - 11) * 10; // 第11名500经验，第50名110经验
        } else if (rank <= 100) {
            return 100 - (rank - 51) * 2; // 第51名100经验，第100名2经验
        }
        return 0;
    }

    /**
     * 发送合并的排行榜奖励
     * @param playerData 玩家奖励数据
     */
    @staticToInstance(ModernRankingService)
    private static async sendCombinedRankingReward(playerData: {
        playerId: string;
        playerName: string;
        rewards: Array<{
            type: RankingType;
            rank: number;
            expReward: number;
        }>;
        totalExpReward: number;
    }) {
        try {
            const title = '🏆排行榜结算奖励';
            
            // 构建邮件内容
            let content = `恭喜你在本周排行榜结算中获得奖励！\n\n`;
            
            // 添加每个排行榜的详细信息
            for (const reward of playerData.rewards) {
                const typeName = this.getRankingTypeName(reward.type);
                content += `📊${typeName}排行榜：第${reward.rank}名\n`;
            }
            
            content += `\n🎁奖励已通过附件发放，请注意查收！`;
            
            // 创建经验道具
            const expItem = sdk.prop.createProp({ 
                type: ItemType.资源, 
                id: '经验值', 
                count: playerData.totalExpReward
            });
            
            console.log(`发送合并排行榜奖励邮件给玩家: ${playerData.playerId}, 总奖励: ${playerData.totalExpReward}经验`);
            
            // 发送邮件
            await sdk.mail.send('admin', playerData.playerId, 30, title, content, [expItem]);
            
        } catch (error) {
            console.error('发送合并排行榜奖励失败:', error);
        }
    }

    /**
     * 发送排行榜奖励（保留原方法以兼容）
     * @param player 玩家信息
     * @param type 排行榜类型
     */
    @staticToInstance(ModernRankingService)
    private static async sendRankingReward(player: RankingItem, type: RankingType) {
        try {
            const expReward = this.calculateExpReward(player.rank);
            
            if (expReward > 0) {
                const title = `${this.getRankingTypeName(type)}排行榜奖励`;
                const content = `恭喜你在${this.getRankingTypeName(type)}排行榜中获得第${player.rank}名！\n奖励经验值：${expReward}`;
                
                // 发送个人邮件奖励
                const expItem = sdk.prop.createProp({ type: ItemType.资源, id: '经验值', count: expReward });
                
                console.log(`发送排行榜奖励邮件给玩家: ${player.playerId}, 奖励: ${expReward}经验`);
                
                // 确保邮件存储到内存中，而不是直接发送给在线玩家
                await sdk.mail.send('admin', player.playerId, 30, title, content, [expItem]);
            }
            
        } catch (error) {
            console.error('发送排行榜奖励失败:', error);
        }
    }
    
    /**
     * 获取排行榜类型名称
     * @param type 排行榜类型
     * @returns 排行榜类型名称
     */
    @staticToInstance(ModernRankingService)
    private static getRankingTypeName(type: RankingType): string {
        switch (type) {
            case RankingType.等级:
                return '等级';
            case RankingType.金币:
                return '金币';
            case RankingType.签到:
                return '签到';
            case RankingType.战力:
                return '战力';
            default:
                return '未知';
        }
    }
    
    /**
     * 手动结算排行榜（管理员功能）
     */
    @staticToInstance(ModernRankingService)
    static async manualSettlement() {
        await this.performSettlement();
    }
    
    /**
     * 更新所有玩家的排行榜数据
     */
    @staticToInstance(ModernRankingService)
    static async updateAllPlayersRanking() {
        try {
            const players = sdk.user.getPlayers();
            
            for (const player of players) {
                // 更新等级排行榜
                await this.updatePlayerRanking(player, RankingType.等级, 0);
                
                // 更新金币排行榜
                await this.updatePlayerRanking(player, RankingType.金币, 0);
                
                // 更新签到排行榜
                await this.updatePlayerRanking(player, RankingType.签到, 0);
                
                // 更新战力排行榜
                await this.updatePlayerRanking(player, RankingType.战力, 0);
            }
            
            console.log('所有玩家排行榜数据更新完成');
            
        } catch (error) {
            console.error('更新所有玩家排行榜数据失败:', error);
        }
    }
    
    /**
     * 初始化排行榜数据（如果为空）
     */
    @staticToInstance(ModernRankingService)
    static async initializeRankingData() {
        try {
            const players = sdk.user.getPlayers();
            if (players.length > 0) {
                console.log('初始化排行榜数据...');
                await this.updateAllPlayersRanking();
                console.log('排行榜数据初始化完成');
            }
        } catch (error) {
            console.error('初始化排行榜数据失败:', error);
        }
    }
} 